#include "tcp_server.h"

TcpServer::TcpServer(QObject *parent) : QTcpServer(parent)
{
    connect(this, SIGNAL(newConnection()), this, SLOT(newConnection()));
}

TcpServer::~TcpServer()
{
    qDebug()<<"关闭tcp服务器";
    stop();


    foreach (QThread* thread, clientsThreads) {
        thread->quit();
        //主线程等待子线程结束
        thread->wait();
        delete thread;

        //等同于上面一句
        //或者在构造函数的位置添加connect(thread, &QThread::finished, thread, &QObject::deleteLater);
    }
}

void TcpServer::newConnection()
{
    QTcpSocket *socket = this->nextPendingConnection(); //结束子线程

    TcpClient *client = new TcpClient(socket, this);

    //为每个新连接的套接字建立线程
    QThread *clientThread = new QThread;
    client->moveToThread(clientThread);
    connect(clientThread, &QThread::finished, this, &TcpClient::deleteLater);
    clientThread->start();


    //关闭tcp服务器
    connect(client, &TcpClient::clientDisconnected, this, &TcpServer::disconnected);

    //传递客户端套接字发送的数据
    //connect(client, &TcpClient::sendData, this, &TcpServer::sendData);
    connect(client, static_cast<void (TcpClient::*)(const QString &, int port, const QString &)>(&TcpClient::sendData),
            this, &TcpServer::sendData);

    //转发收到的数据
    connect(client, &TcpClient::receiveData, this, &TcpServer::receiveData);

    //发送客户端成功连接的信号
    emit clientConnected(client->getIP(), client->getPort());


    // QString ip = client->getIP();
    // int port = client->getPort();
    // emit clientConnected(ip, port);
    emit sendData(client->getIP(), client->getPort(), "客户端上线");

    //连接后加入链表
    clients.append(client);
    clientsThreads.append(clientThread);
}

void TcpServer::disconnected()
{
    TcpClient *client = (TcpClient *)sender();
    QString ip = client->getIP();
    int port = client->getPort();
    emit clientDisconnected(ip, port);
    emit sendData(ip, port, "客户端下线");

    //断开连接后从链表中移除
    clients.removeOne(client);
}

bool TcpServer::start(QString ip, int port)
{
    bool ok = listen(QHostAddress(ip), port);
    return ok;
}

void TcpServer::stop()
{
    remove();
    this->close();
}

void TcpServer::writeData(const QString &ip, int port, const QString &data)
{
    foreach (TcpClient *client, clients) {
        if (client->getIP() == ip && client->getPort() == port) {
            client->sendData(data);
            break;
        }
    }
}

void TcpServer::writeData(const QString &data)
{
    foreach (TcpClient *client, clients) {
        client->sendData(data);
    }
}

void TcpServer::remove(const QString &ip, int port)
{
    foreach (TcpClient *client, clients) {
        if (client->getIP() == ip && client->getPort() == port) {
            client->abort();
            break;
        }
    }
}

void TcpServer::remove()
{
    foreach (TcpClient *client, clients) {
        client->abort();
    }
}
